%option noyywrap
%option noinput
%option nounput
%option nodefault
%option batch
%option debug
%option warn

%{
#include <string>
#include <iostream>
#include <cstdlib>
#include <memory>
#include <ast/ast.h>
#include "parser.h"
#include <parser/front.h>

#define YY_USER_ACTION loc.columns(yyleng);
%}

%x COMMENT

WHITESPACE    [ \t\r]

NEWLINE       \n

INT           ([0-9])+

FLOAT         ([0-9])+(\.[0-9])+

IDEN          [a-zA-Z_][a-zA-Z0-9_]*

%%

%{
  yy::location & loc = front.loc;
  loc.step();
%}

"int"     { return yy::Parser::make_INT(loc); }
"float"   { return yy::Parser::make_FLOAT(loc); }
"void"    { return yy::Parser::make_VOID(loc); }
"const"   { return yy::Parser::make_CONST(loc); }

"return"    { return yy::Parser::make_RETURN(loc); }
"if"        { return yy::Parser::make_IF(loc); }
"else"      { return yy::Parser::make_ELSE(loc); }
"while"     { return yy::Parser::make_WHILE(loc); }
"break"     { return yy::Parser::make_BREAK(loc); }
"continue"  { return yy::Parser::make_CONTINUE(loc); }

"//".*  { loc.lines(yyleng); }
"/*"    { BEGIN(COMMENT); }
<COMMENT>"*/" { BEGIN(INITIAL); }
<COMMENT>.|\n { loc.lines(yyleng); }

">"   { /* return yy::Parser::make_G(loc); */ }
"<"   { /* return yy::Parser::make_L(loc); */ }
">="  { /* return yy::Parser::make_GE(loc); */ }
"<="  { /* return yy::Parser::make_LE(loc); */ }

"=="  { return yy::Parser::make_EEQ(loc); }
"!="  { return yy::Parser::make_NEQ(loc); }

"||"  { /* return yy::Parser::make_OR(loc); */ }
"&&"  { /* return yy::Parser::make_AND(loc); */ }

";"   { return yy::Parser::make_SEMICOLON(loc); }
","   { return yy::Parser::make_COMMA(loc); }
"="   { return yy::Parser::make_EQ(loc); }

"+"   { return yy::Parser::make_ADD(loc); }
"-"   { return yy::Parser::make_SUB(loc); }
"*"   { return yy::Parser::make_MUL(loc); }
"/"   { return yy::Parser::make_DIV(loc); }
"%"   { return yy::Parser::make_REM(loc); }

"("   { return yy::Parser::make_LB_L(loc); }
")"   { return yy::Parser::make_RB_L(loc); }
"["   { return yy::Parser::make_LB_M(loc); }
"]"   { return yy::Parser::make_RB_M(loc); }
"{"   { const_int_stack.new_stack(); return yy::Parser::make_LB_H(loc); }
"}"   { const_int_stack.delete_last_stack(); return yy::Parser::make_RB_H(loc); }

{INT}   { return yy::Parser::make_INT_NUMBER(atoi(yytext), loc); }
{FLOAT} { return yy::Parser::make_FLOAT_NUMBER(atof(yytext), loc); }
{IDEN}  { return yy::Parser::make_IDEN(yytext, loc); }

{WHITESPACE}+  { loc.step(); }
{NEWLINE}+     { loc.lines(yyleng); loc.step(); }

<<EOF>>   { return yy::Parser::make_YYEOF(loc); }

.     {
        std::cout << "undefined word: " << yytext << std::endl;
        return yy::Parser::make_YYUNDEF(loc);
      }

%%
